/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.mobiwebinc.compconn.client;

import com.mobiwebinc.compconn.configuration.Constant;
import com.mobiwebinc.compconn.gui.ConfigurationGUI;
import java.awt.Menu;
import java.awt.MenuItem;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Vector;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;

/**
 *
 * @author suraj
 */
public class ClientList implements ActionListener {

    private static ClientList clientList;
    private HashMap<String, ClientHandler> handlers;
    Menu mnu;
    JMenu jmnu;

    private ClientList() {
        mnu = new Menu(Constant.DISCONNECT);
        jmnu = new JMenu(Constant.DISCONNECT);
        handlers = new HashMap<String, ClientHandler>();
    }

    public static ClientList getInstance() {
        if (clientList == null) {
            clientList = new ClientList();
        }
        return clientList;
    }

    public void removeClient(ClientHandler handler) {
        removeClientWithName(handler.getClientConfiguration().getName());
    }

    public Menu getMenu() {
        return mnu;
    }

    public JMenu getJMenu() {
        return jmnu;
    }

    public synchronized void updateClient(ClientHandler handler) {
        String name = handler.getClientConfiguration().getName();
        if (!(handlers.containsKey(name) && handlers.get(name) == handler)) {
            addClient(handler);
            removeInconsistant();
            generateMenus();
        }
    }

    public synchronized void addClient(ClientHandler handler) {
        String key = uniqName(handler.getClientConfiguration().getName());
        handler.getClientConfiguration().setName(key);
        getHandlers().put(key, handler);
        generateMenus();
    }

    private void disconnectClientWithName(String cmd) {
        getHandlers().get(cmd).disconnect();
    }

    public void disconnectAll() {
        for(String key: getHandlers().keySet()) {
            disconnectClientWithName(key);
        }
        getHandlers().clear();
        generateMenus();
    }

    private void generateMenus() {
        mnu.removeAll();
        jmnu.removeAll();
        for (String name : getHandlers().keySet()) {
            MenuItem item = new MenuItem(name);
            item.addActionListener(this);
            JMenuItem jtem = new JMenuItem(name);
            jtem.addActionListener(this);
            jmnu.add(jtem);
            mnu.add(item);
        }
    }

    public void actionPerformed(ActionEvent e) {
        String cmd = e.getActionCommand();
        int option = JOptionPane.showConfirmDialog(ConfigurationGUI.getInstance(), String.format(Constant.ASK_DISCONNECT_MESSAGE, cmd), Constant.DISCONNECT + " " + cmd, JOptionPane.YES_NO_OPTION);
        if (option == JOptionPane.YES_OPTION) {
            disconnectClientWithName(cmd);
            removeClientWithName(cmd);
        }
    }

    private void removeClientWithName(String name) {
        getHandlers().remove(name);
        generateMenus();
    }

    private void removeInconsistant() {
        Vector<String> removeList = new Vector<String>();
        for (Entry<String, ClientHandler> entry : getHandlers().entrySet()) {
            if (!entry.getKey().equals(entry.getValue().getClientConfiguration().getName())) {
                removeList.add(entry.getKey());
            }
        }
        for (String key : removeList) {
            getHandlers().remove(key);
        }
    }

    private String uniqName(String name) {
        String newName = name;
        int i = 1;
        while (getHandlers().containsKey(newName)) {
            newName = String.format("%s (%d)", name, i++);
        }
        return newName;
    }

    /**
     * @return the handlers
     */
    public synchronized HashMap<String, ClientHandler> getHandlers() {
        return handlers;
    }

    /**
     * @param handlers the handlers to set
     */
    public synchronized void setHandlers(HashMap<String, ClientHandler> handlers) {
        this.handlers = handlers;
    }
}
